/*
 ******************************************************************************
 * Parts of this code sample are licensed under Apache License, Version 2.0   *
 * Copyright (c) 2009, Android Open Handset Alliance. All rights reserved.    *
 *																			  *																			*
 * Except as noted, this code sample is offered under a modified BSD license. *
 * Copyright (C) 2010, Motorola Mobility, Inc. All rights reserved.           *
 * 																			  *
 * For more details, see MOTODEV_Studio_for_Android_LicenseNotices.pdf        * 
 * in your installation folder.                                               *
 ******************************************************************************
 */
package me.evis.mobile.sms2cal.provider;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

public class CalEventContentProvider extends ContentProvider {

    private Sms2CalDbHelper dbHelper;
    private static HashMap<String, String> CALEVENT_PROJECTION_MAP;
    private static final String TABLE_NAME = "calevent";
    private static final String AUTHORITY = "me.evis.mobile.sms2cal.provider.caleventcontentprovider";

    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
            + "/" + TABLE_NAME);
    public static final Uri _ID_FIELD_CONTENT_URI = Uri.parse("content://"
            + AUTHORITY + "/" + TABLE_NAME.toLowerCase());
    public static final Uri PARSELOG_ID_FIELD_CONTENT_URI = Uri
            .parse("content://" + AUTHORITY + "/" + TABLE_NAME.toLowerCase()
                    + "/parselog_id");
    public static final Uri SUMMARY_FIELD_CONTENT_URI = Uri.parse("content://"
            + AUTHORITY + "/" + TABLE_NAME.toLowerCase() + "/summary");
    public static final Uri LOCATION_FIELD_CONTENT_URI = Uri.parse("content://"
            + AUTHORITY + "/" + TABLE_NAME.toLowerCase() + "/location");
    public static final Uri DTSTAMP_FIELD_CONTENT_URI = Uri.parse("content://"
            + AUTHORITY + "/" + TABLE_NAME.toLowerCase() + "/dtstamp");
    public static final Uri DTSTART_FIELD_CONTENT_URI = Uri.parse("content://"
            + AUTHORITY + "/" + TABLE_NAME.toLowerCase() + "/dtstart");
    public static final Uri DTEND_FIELD_CONTENT_URI = Uri.parse("content://"
            + AUTHORITY + "/" + TABLE_NAME.toLowerCase() + "/dtend");
    public static final Uri DESCRIPTION_FIELD_CONTENT_URI = Uri
            .parse("content://" + AUTHORITY + "/" + TABLE_NAME.toLowerCase()
                    + "/description");
    public static final Uri CLASSIFICATION_FIELD_CONTENT_URI = Uri
            .parse("content://" + AUTHORITY + "/" + TABLE_NAME.toLowerCase()
                    + "/classification");
    public static final Uri CATEGORIES_FIELD_CONTENT_URI = Uri
            .parse("content://" + AUTHORITY + "/" + TABLE_NAME.toLowerCase()
                    + "/categories");
    public static final Uri TARGET_GCAL_ID_FIELD_CONTENT_URI = Uri
            .parse("content://" + AUTHORITY + "/" + TABLE_NAME.toLowerCase()
                    + "/target_gcal_id");

    public static final String DEFAULT_SORT_ORDER = "_id ASC";

    private static final UriMatcher URL_MATCHER;

    private static final int CALEVENT = 1;
    private static final int CALEVENT__ID = 2;
    private static final int CALEVENT_PARSELOG_ID = 3;
    private static final int CALEVENT_SUMMARY = 4;
    private static final int CALEVENT_LOCATION = 5;
    private static final int CALEVENT_DTSTAMP = 6;
    private static final int CALEVENT_DTSTART = 7;
    private static final int CALEVENT_DTEND = 8;
    private static final int CALEVENT_DESCRIPTION = 9;
    private static final int CALEVENT_CLASSIFICATION = 10;
    private static final int CALEVENT_CATEGORIES = 11;
    private static final int CALEVENT_TARGET_GCAL_ID = 12;

    // Content values keys (using column names)
    public static final String _ID = "_id";
    public static final String PARSELOG_ID = "parselog_id";
    public static final String SUMMARY = "summary";
    public static final String LOCATION = "location";
    public static final String DTSTAMP = "dtStamp";
    public static final String DTSTART = "dtStart";
    public static final String DTEND = "dtEnd";
    public static final String DESCRIPTION = "description";
    public static final String CLASSIFICATION = "classification";
    public static final String CATEGORIES = "categories";
    public static final String TARGET_GCAL_ID = "target_gcal_id";

    public boolean onCreate() {
        dbHelper = new Sms2CalDbHelper(getContext(), true);
        return (dbHelper == null) ? false : true;
    }

    public Cursor query(Uri url, String[] projection, String selection,
            String[] selectionArgs, String sort) {
        SQLiteDatabase mDB = dbHelper.getReadableDatabase();
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        switch (URL_MATCHER.match(url)) {
        case CALEVENT:
            qb.setTables(TABLE_NAME);
            qb.setProjectionMap(CALEVENT_PROJECTION_MAP);
            break;
        case CALEVENT__ID:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("_id=" + url.getPathSegments().get(1));
            break;
        case CALEVENT_PARSELOG_ID:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("parselog_id='" + url.getPathSegments().get(2) + "'");
            break;
        case CALEVENT_SUMMARY:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("summary='" + url.getPathSegments().get(2) + "'");
            break;
        case CALEVENT_LOCATION:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("location='" + url.getPathSegments().get(2) + "'");
            break;
        case CALEVENT_DTSTAMP:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("dtstamp='" + url.getPathSegments().get(2) + "'");
            break;
        case CALEVENT_DTSTART:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("dtstart='" + url.getPathSegments().get(2) + "'");
            break;
        case CALEVENT_DTEND:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("dtend='" + url.getPathSegments().get(2) + "'");
            break;
        case CALEVENT_DESCRIPTION:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("description='" + url.getPathSegments().get(2) + "'");
            break;
        case CALEVENT_CLASSIFICATION:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("classification='" + url.getPathSegments().get(2)
                    + "'");
            break;
        case CALEVENT_CATEGORIES:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("categories='" + url.getPathSegments().get(2) + "'");
            break;
        case CALEVENT_TARGET_GCAL_ID:
            qb.setTables(TABLE_NAME);
            qb.appendWhere("target_gcal_id='" + url.getPathSegments().get(2)
                    + "'");
            break;

        default:
            throw new IllegalArgumentException("Unknown URL " + url);
        }
        String orderBy = "";
        if (TextUtils.isEmpty(sort)) {
            orderBy = DEFAULT_SORT_ORDER;
        } else {
            orderBy = sort;
        }
        Cursor c = qb.query(mDB, projection, selection, selectionArgs, null,
                null, orderBy);
        c.setNotificationUri(getContext().getContentResolver(), url);
        return c;
    }

    public String getType(Uri url) {
        switch (URL_MATCHER.match(url)) {
        case CALEVENT:
            return "vnd.android.cursor.dir/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT__ID:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_PARSELOG_ID:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_SUMMARY:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_LOCATION:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_DTSTAMP:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_DTSTART:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_DTEND:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_DESCRIPTION:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_CLASSIFICATION:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_CATEGORIES:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";
        case CALEVENT_TARGET_GCAL_ID:
            return "vnd.android.cursor.item/vnd.me.evis.mobile.sms2cal.provider.calevent";

        default:
            throw new IllegalArgumentException("Unknown URL " + url);
        }
    }

    public Uri insert(Uri url, ContentValues initialValues) {
        SQLiteDatabase mDB = dbHelper.getWritableDatabase();
        long rowID;
        ContentValues values;
        if (initialValues != null) {
            values = new ContentValues(initialValues);
        } else {
            values = new ContentValues();
        }
        if (URL_MATCHER.match(url) != CALEVENT) {
            throw new IllegalArgumentException("Unknown URL " + url);
        }

        rowID = mDB.insert("calevent", "calevent", values);
        if (rowID > 0) {
            Uri uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
            getContext().getContentResolver().notifyChange(uri, null);
            return uri;
        }
        throw new SQLException("Failed to insert row into " + url);
    }

    public int delete(Uri url, String where, String[] whereArgs) {
        SQLiteDatabase mDB = dbHelper.getWritableDatabase();
        int count;
        String segment = "";
        switch (URL_MATCHER.match(url)) {
        case CALEVENT:
            count = mDB.delete(TABLE_NAME, where, whereArgs);
            break;
        case CALEVENT__ID:
            segment = url.getPathSegments().get(1);
            count = mDB.delete(TABLE_NAME,
                    "_id="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_PARSELOG_ID:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "parselog_id="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_SUMMARY:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "summary="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_LOCATION:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "location="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_DTSTAMP:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "dtstamp="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_DTSTART:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "dtstart="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_DTEND:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "dtend="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_DESCRIPTION:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "description="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_CLASSIFICATION:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "classification="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_CATEGORIES:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "categories="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_TARGET_GCAL_ID:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.delete(TABLE_NAME,
                    "target_gcal_id="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;

        default:
            throw new IllegalArgumentException("Unknown URL " + url);
        }
        getContext().getContentResolver().notifyChange(url, null);
        return count;
    }

    public int update(Uri url, ContentValues values, String where,
            String[] whereArgs) {
        SQLiteDatabase mDB = dbHelper.getWritableDatabase();
        int count;
        String segment = "";
        switch (URL_MATCHER.match(url)) {
        case CALEVENT:
            count = mDB.update(TABLE_NAME, values, where, whereArgs);
            break;
        case CALEVENT__ID:
            segment = url.getPathSegments().get(1);
            count = mDB.update(TABLE_NAME, values,
                    "_id="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_PARSELOG_ID:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "parselog_id="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_SUMMARY:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "summary="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_LOCATION:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "location="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_DTSTAMP:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "dtstamp="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_DTSTART:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "dtstart="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_DTEND:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "dtend="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_DESCRIPTION:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "description="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_CLASSIFICATION:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "classification="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_CATEGORIES:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "categories="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;
        case CALEVENT_TARGET_GCAL_ID:
            segment = "'" + url.getPathSegments().get(2) + "'";
            count = mDB.update(TABLE_NAME, values,
                    "target_gcal_id="
                            + segment
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereArgs);
            break;

        default:
            throw new IllegalArgumentException("Unknown URL " + url);
        }
        getContext().getContentResolver().notifyChange(url, null);
        return count;
    }

    static {
        URL_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase(), CALEVENT);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/#",
                CALEVENT__ID);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/parselog_id"
                + "/*", CALEVENT_PARSELOG_ID);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/summary"
                + "/*", CALEVENT_SUMMARY);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/location"
                + "/*", CALEVENT_LOCATION);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/dtstamp"
                + "/*", CALEVENT_DTSTAMP);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/dtstart"
                + "/*", CALEVENT_DTSTART);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/dtend"
                + "/*", CALEVENT_DTEND);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/description"
                + "/*", CALEVENT_DESCRIPTION);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase()
                + "/classification" + "/*", CALEVENT_CLASSIFICATION);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase() + "/categories"
                + "/*", CALEVENT_CATEGORIES);
        URL_MATCHER.addURI(AUTHORITY, TABLE_NAME.toLowerCase()
                + "/target_gcal_id" + "/*", CALEVENT_TARGET_GCAL_ID);

        CALEVENT_PROJECTION_MAP = new HashMap<String, String>();
        CALEVENT_PROJECTION_MAP.put(_ID, "_id");
        CALEVENT_PROJECTION_MAP.put(PARSELOG_ID, "parselog_id");
        CALEVENT_PROJECTION_MAP.put(SUMMARY, "summary");
        CALEVENT_PROJECTION_MAP.put(LOCATION, "location");
        CALEVENT_PROJECTION_MAP.put(DTSTAMP, "dtstamp");
        CALEVENT_PROJECTION_MAP.put(DTSTART, "dtstart");
        CALEVENT_PROJECTION_MAP.put(DTEND, "dtend");
        CALEVENT_PROJECTION_MAP.put(DESCRIPTION, "description");
        CALEVENT_PROJECTION_MAP.put(CLASSIFICATION, "classification");
        CALEVENT_PROJECTION_MAP.put(CATEGORIES, "categories");
        CALEVENT_PROJECTION_MAP.put(TARGET_GCAL_ID, "target_gcal_id");

    }
}
